﻿using CSBackup_Web.Models;
using CSBackup_Web.Sources;
using CSBackup_Web.Sources.Override;
using CSBackup_Web.Sources.ui_Legacy;
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Threading.Tasks;
using System.Web;
using System.Web.Mvc;

namespace CSBackup_Web.Controllers
{
    using Directory = System.IO.Directory;
    using DirectoryInfo = System.IO.DirectoryInfo;
    using Path = System.IO.Path;

    [Authorize]
    public class SettingsController : Controller
    {
        [HttpGet]
        public ActionResult NewPrjName()
        {
            return View(new NewPrjNameModel());
        }

        [HttpPost]
        public ActionResult NewPrjName(NewPrjNameModel m)
        {
            if (TempData["model"] != null)
            {
                ((NewPrjNameModel)TempData["model"]).ProjectName = m.ProjectName;
                m = (NewPrjNameModel)TempData["model"];
            }

            string path = Path.Combine(Server.MapPath("~/App_Data"), User.Identity.Name, m.ProjectName);
            if (Directory.Exists(path))
            {
                TempData["alert"] = "此项目名称已存在";
                TempData["model"] = m;
                return View(m);
            }
            else
            {
                TempData["model"] = new NewPrjFileModel();
                ((NewPrjFileModel)TempData["model"]).ProjectName = m.ProjectName;
                ((NewPrjFileModel)TempData["model"]).ProjInfo = m.ProjInfo;
                ((NewPrjFileModel)TempData["model"]).ActiveTab = m.ActiveTab;
                return RedirectToAction("NewPrjFile");
            }
        }

        [HttpGet]
        public ActionResult NewPrjFile()
        {
            NewPrjFileModel m = new NewPrjFileModel();
            if (TempData["model"] != null)
            {
                m = (NewPrjFileModel)TempData["model"];
            }

            TempData["model"] = m;
            return View(m);
        }

        [HttpPost]
        public ActionResult NewPrjFile(HttpPostedFileBase file)
        {
            NewPrjFileModel m = new NewPrjFileModel();
            if (TempData["model"] != null)
            {
                m = (NewPrjFileModel)TempData["model"];
            }

            if (file != null && file.ContentLength > 0)
            {
                string filePath = Path.Combine(System.Web.HttpContext.Current.Server.MapPath("~/App_Data"), User.Identity.Name, m.ProjectName, "Resources", file.FileName);
                string directory = Path.GetDirectoryName(filePath);

                bool isFileExists = m.FileList.Contains(filePath);
                if (!isFileExists)
                {
                    if (!Directory.Exists(directory))
                    {
                        Directory.CreateDirectory(directory);
                    }
                    file.SaveAs(filePath);
                    m.FileList.Add(filePath);
                    m.FileListValue.Add(false);
                }
                else
                {
                    TempData["alert"] = "此文件已存在";
                }
            }

            TempData["model"] = m;
            return View(m);
        }

        public ActionResult NewPrjFileDone()
        {
            NewPrjFileModel m = new NewPrjFileModel();
            if (TempData["model"] != null)
            {
                m = (NewPrjFileModel)TempData["model"];
            }

            ProjectInfo projInfo = new ProjectInfo();

            if (m.ProjInfo.IsNew)
            {
                projInfo.PrjName = m.ProjectName;
                projInfo.PrjLocation = Path.Combine(System.Web.HttpContext.Current.Server.MapPath("~/App_Data"), User.Identity.Name, m.ProjectName);
                Directory.CreateDirectory(projInfo.DiffBkpPath);
                Directory.CreateDirectory(projInfo.FullBkpPath);
                Directory.CreateDirectory(projInfo.DiffIncBkpPath);
                Directory.CreateDirectory(projInfo.IncBkpPath);
                Directory.CreateDirectory(projInfo.RecoveryPath);
                projInfo.IsNew = false;
            }
            if (projInfo.SaveProject() == 0)
            {
                projInfo.CurrentBackup.FileList = m.FileList;

                TempData["model"] = new HomeModel();
                ((HomeModel)TempData["model"]).ProjInfo = projInfo;
                return RedirectToAction("Index", "Home");
            }
            else
            {
                TempData["alert"] = "保存工程文件失败";
                return View(m);
            }
        }

        [HttpPost]
        public ActionResult RemoveFile(NewPrjFileModel m)
        {
            if (TempData["model"] != null)
            {
                ((NewPrjFileModel)TempData["model"]).FileListValue = m.FileListValue;
                m = (NewPrjFileModel)TempData["model"];
            }

            for (int i = m.FileList.Count - 1; i > -1; i--)
            {
                if (m.FileListValue[i])
                {
                    m.FileList.RemoveAt(i);
                    m.FileListValue.RemoveAt(i);
                    m.ProjInfo.CurrentBackup.FileList.RemoveAt(i);
                }
            }

            TempData["model"] = m;
            return RedirectToAction("NewPrjFile");
        }

        [HttpGet]
        public ActionResult NewPrjFileCancel()
        {
            NewPrjFileModel m = new NewPrjFileModel();
            if (TempData["model"] != null)
            {
                m = (NewPrjFileModel)TempData["model"];
            }
            if (m.ProjInfo.IsNew)
                return RedirectToAction("NewPrjName");
            else
                return RedirectToAction("Index", "Home");
        }

        [HttpGet]
        public ActionResult ChoosePrj()
        {
            ChoosePrjModel m = new ChoosePrjModel();
            if (TempData["model"] != null)
            {
                m = (ChoosePrjModel)TempData["model"];
            }
            return View(m);
        }

        [HttpPost]
        public ActionResult ChoosePrj(ChoosePrjModel m)
        {
            string prjFile = Path.Combine(Server.MapPath("~/App_Data"), User.Identity.Name, m.ChosenPrjName, m.ChosenPrjName + ".bakprj");
            frmUI1.CleanUpPrj(m.ProjInfo);  //清空当前工程句柄
            m.ProjInfo.IsNew = false;  //不是新创建的工程
            ToolConfigFile.LoadPrjFromFile(m.ProjInfo, prjFile);

            TempData["model"] = new HomeModel();
            ((HomeModel)TempData["model"]).ProjInfo = m.ProjInfo;
            return RedirectToAction("Index", "Home");
        }

        [HttpGet]
        public ActionResult AutoBkp()
        {
            return View(new AutoBkpModel());
        }

        [HttpPost]
        public ActionResult AutoBkp(AutoBkpModel m)
        {
            RegistryKey key = Registry.LocalMachine.OpenSubKey("software").OpenSubKey("YunGe", true);
            if (key == null)
            {
                key = Registry.LocalMachine.OpenSubKey("software", true).CreateSubKey("YunGe");
            }
            if (m.TaskName == "")
            {
                TempData["alert"] = "请输入任务名称";
                return View(m);
            }
            if (key.OpenSubKey(m.TaskName) != null)
            {
                TempData["alert"] = "该名称已被使用";
                return View(m);
            }

            int interval = 1, repeatCount;

            switch (m.Method)
            {
                case "once":
                    repeatCount = 1;
                    break;
                case "cycle":
                    repeatCount = -1;
                    switch (m.Cycle)
                    {
                        case "daily":
                            interval = 1440;
                            break;
                        case "weekly":
                            interval = 10080;
                            break;
                        case "monthly":
                            interval = 40320;
                            break;
                    }
                    break;
                case "customize":
                    repeatCount = -1;
                    switch (m.IntervalUnit)
                    {
                        case "minute":
                            interval = m.IntervalValue;
                            break;
                        case "hour":
                            interval = m.IntervalValue * 60;
                            break;
                        case "day":
                            interval = m.IntervalValue * 60 * 24;
                            break;
                        default:
                            TempData["alert"] = "时间间隔单位无法识别";
                            return View(m);
                    }
                    break;
                default:
                    TempData["alert"] = "备份方式无法识别";
                    return View(m);
            }

            string newName = m.TaskName;
            key.CreateSubKey(newName);
            key = key.OpenSubKey(newName, true);
            key.SetValue("interval", interval.ToString());
            DateTime startTime = DateTime.ParseExact(m.StringDate, "d", CultureInfo.InvariantCulture);
            startTime = startTime.AddHours(m.Hour);
            startTime = startTime.AddMinutes(m.Minute);
            key.SetValue("startTime", startTime.ToString());
            key.SetValue("endTime", new DateTime(2099, 4, 4).ToString());
            key.SetValue("repeatCount", repeatCount.ToString());
            key.SetValue("lastBackup", DateTime.Now.ToString());
            key.SetValue("prjPath", m.ProjInfo.BkpPrjFile);
            key.Close();

            TempData["alert"] = "设定成功！";
            return RedirectToAction("Index", "Home");
        }

        [HttpGet]
        public ActionResult BkpSvc()
        {
            RegistryKey key = Registry.LocalMachine.OpenSubKey("software").OpenSubKey("YunGe", true);
            if (key == null)
            {
                key = Registry.LocalMachine.OpenSubKey("software", true).CreateSubKey("YunGe");
            }
            string[] keyNames = key.GetSubKeyNames();

            BkpSvcModel m = new BkpSvcModel();

            foreach (string sub in keyNames)
            {
                RegistryKey subKey = key.OpenSubKey(sub, true);
                string intervalStr = subKey.GetValue("interval") as string;
                string startTimeStr = subKey.GetValue("startTime") as string;
                string endTimeStr = subKey.GetValue("endTime") as string;
                string repeatStr = subKey.GetValue("repeatCount") as string;
                string lastStr = subKey.GetValue("lastBackup") as string;
                string prjPath = subKey.GetValue("prjPath") as string;

                int intervalInt = Int32.Parse(intervalStr);
                if (intervalInt > 1440)
                    intervalStr = intervalInt / 1440 + "天";
                else if (intervalInt > 60)
                    intervalStr = intervalInt / 60 + "小时";
                else
                    intervalStr = intervalInt + "分钟";

                List<string> item = new List<string>();
                item.Add(sub);
                item.Add(intervalStr);
                item.Add(startTimeStr);
                if ((repeatStr != null) && (repeatStr != "0"))
                    item.Add("进行中");
                else
                    item.Add("完成");

                m.Items.Add(item);
                m.ItemCheck.Add(false);
            }
            TempData["BkpSvc"] = m;
            return View(m);
        }

        [HttpPost]
        public ActionResult BkpSvc(BkpSvcModel m)
        {
            m.Items = ((BkpSvcModel)TempData["BkpSvc"]).Items;
            for (int i = m.Items.Count - 1; i >= 0; i--)
            {
                if (m.ItemCheck[i])
                {
                    RegistryKey key = Registry.LocalMachine.OpenSubKey("software").OpenSubKey("YunGe", true);
                    string name = m.Items[i][0];
                    key.DeleteSubKey(name);
                }
            }
            return RedirectToAction("BkpSvc");
        }

        [HttpGet]
        public ActionResult PrtRcvr()
        {
            PrtRcvrModel m = new PrtRcvrModel();
            if (TempData["model"] != null)
            {
                m = (PrtRcvrModel)TempData["model"];
            }
            return View(m);
        }

        [HttpGet]
        public ActionResult PrtRcvrSelectAll()
        {
            PrtRcvrModel m = (PrtRcvrModel)TempData["prtRcvr"];
            for (int i = 0; i < m.FileInfoValue.Count; i++)
            {
                m.FileInfoValue[i] = true;
            }
            TempData["prtRcvr"] = m;
            return RedirectToAction("PrtRcvr");
        }
        [HttpGet]
        public ActionResult PrtRcvrCancelAll()
        {
            PrtRcvrModel m = (PrtRcvrModel)TempData["prtRcvr"];
            for (int i = 0; i < m.FileInfoValue.Count; i++)
            {
                m.FileInfoValue[i] = false;
            }
            TempData["prtRcvr"] = m;
            return RedirectToAction("PrtRcvr");
        }

        [HttpPost]
        public async Task<ActionResult> PrtRcvrClicked(PrtRcvrModel m)
        {
            //Pull info from session
            if (TempData["model"] != null)
            {
                ((PrtRcvrModel)TempData["model"]).FileInfoValue = m.FileInfoValue;
                m = (PrtRcvrModel)TempData["model"];
            }
            try
            {
                List<FileDetail> files = m.ProjInfo.SelectedFileList;
                List<FileDetail> dirs = m.ProjInfo.SelectedDirList;

                List<String> filesToMarshal = new List<String>();
                List<String> dirsToMarshal = new List<String>();
                List<String> difToMarshal = new List<String>();

                BackupInfo backInfo = new BackupInfo();

                //将选中的文件名放入字符串数组中
                for (int i = 0; i < files.Count; i++)
                {
                    if (m.FileInfoValue[i])
                    {
                        filesToMarshal.Add(files[i].FileName);
                    }
                }

                //将字符串数组放入后台操作线程中
                backInfo = m.ProjInfo.SelectedBackup;

                // Clean the directory
                string recoveryPath = Path.Combine(m.ProjInfo.PrjLocation, "Recover");
                foreach (string file in Directory.GetFiles(recoveryPath))
                {
                    System.IO.File.Delete(file);
                }
                foreach (string dir in Directory.GetDirectories(recoveryPath))
                {
                    Directory.Delete(dir, true);
                }

                //恢复部分文件
                if (backInfo != null && m.ProjInfo != null)
                {
                    await PrtRcvr(filesToMarshal, m.ProjInfo.BkpPrjFile, backInfo);

                    // Collect files and zip them for downloading
                    string zipLocation = Path.Combine(recoveryPath, "recovery.zip");
                    foreach (string file in Directory.GetFiles(recoveryPath))
                    {
                        Common.AddFileToZip(zipLocation, file);
                    }
                    Response.ContentType = "application/zip";
                    Response.AppendHeader("Content-Disposition", "attachment; filename=Recovery.zip");
                    Response.TransmitFile(zipLocation);
                    Response.End();

                    TempData["alert"] = "恢复完成";
                    TempData["model"] = new HomeModel();
                    ((HomeModel)TempData["model"]).ActiveTab = 1;
                    ((HomeModel)TempData["model"]).ProjInfo = m.ProjInfo;
                    return RedirectToAction("Index", "Home");
                }
            }
            catch (Exception exception)
            {
                TempData["alert"] = exception.Message;
                TempData["model"] = m;
                return RedirectToAction("PrtRcvr");
            }
            TempData["model"] = m;
            return RedirectToAction("PrtRcvr");
        }
        private async Task<int> PrtRcvr(List<string> files, string projPath, BackupInfo backInfo)
        {
            BackupRecovery.RecoveryPartRecoveryPoint(files, projPath, backInfo);
            return 1;
        }
    }
}
